
package com.jf.cloud.product.controller.platform;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.jf.cloud.api.auth.constant.SysTypeEnum;
import com.jf.cloud.api.multishop.bo.EsShopDetailBO;
import com.jf.cloud.api.multishop.constant.ShopStatus;
import com.jf.cloud.api.multishop.feign.ShopDetailFeignClient;
import com.jf.cloud.api.platform.dto.OfflineHandleEventDTO;
import com.jf.cloud.api.platform.feign.ConfigFeignClient;
import com.jf.cloud.api.product.util.ProductLangUtil;
import com.jf.cloud.api.vo.EsPageVO;
import com.jf.cloud.common.constant.Constant;
import com.jf.cloud.common.constant.StatusEnum;
import com.jf.cloud.common.exception.LuckException;
import com.jf.cloud.common.product.constant.SpuStatus;
import com.jf.cloud.common.product.constant.SpuType;
import com.jf.cloud.common.product.constant.SupplierDeliveryType;
import com.jf.cloud.common.product.constant.SupplierSpuType;
import com.jf.cloud.common.product.dto.ProductSearchDTO;
import com.jf.cloud.common.product.dto.SpuDTO;
import com.jf.cloud.common.product.vo.CategoryVO;
import com.jf.cloud.common.product.vo.SpuVO;
import com.jf.cloud.common.product.vo.search.SpuAdminVO;
import com.jf.cloud.common.response.ResponseEnum;
import com.jf.cloud.common.response.ServerResponseEntity;
import com.jf.cloud.common.security.AuthUserContext;
import com.jf.cloud.common.util.ExcelUtil;
import com.jf.cloud.product.dto.SpuPageSearchDTO;
import com.jf.cloud.product.service.*;
import com.jf.cloud.product.vo.CategoryShopVO;
import com.jf.cloud.product.vo.PlatformSpuExcelVO;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import org.apache.commons.math3.stat.descriptive.summary.Product;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.*;

/**
 * @author zz
 * @Date 2021/7/19 16:42
 */
@RestController("platformSpuController")
@RequestMapping("/p/spu")
@Tag(name = "platform-spu信息")
public class SpuController {

    @Autowired
    private SpuService spuService;

    @Autowired
    private ShopDetailFeignClient shopDetailFeignClient;

    @Autowired
    private SpuExcelService spuExcelService;
    @Autowired
    private ShopCartService shopCartService;
    @Autowired
    private CategoryShopService categoryShopService;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private ConfigFeignClient configFeignClient;

    @PutMapping("/to_top")
    @Operation(summary = "通过商品id设置是否置顶" , description = "通过商品id设置是否置顶")
    public ServerResponseEntity<Void> toTopBySpuId(@RequestParam(value = "spuId") Long spuId) {
        SpuVO spuVO = spuService.getBySpuId(spuId);
        if (!Objects.equals(spuVO.getStatus(), StatusEnum.ENABLE.value()) && Objects.equals(spuVO.getIsTop(), StatusEnum.DISABLE.value())) {
            throw new LuckException("只能置顶已上架的商品");
        }
        spuService.toTopBySpuId(spuId);
        return ServerResponseEntity.success();
    }

    @PostMapping("/score_save")
    @Operation(summary = "保存积分spu信息" , description = "保存积分spu信息")
    public ServerResponseEntity<Void> save(@Valid @RequestBody SpuDTO spuDTO) {
        // 发布商品时，需要根据店铺状态判断是否可以发布商品
        ServerResponseEntity<EsShopDetailBO> shopRequest = shopDetailFeignClient.getShopByShopId(AuthUserContext.get().getTenantId());
        EsShopDetailBO shopDetail = shopRequest.getData();
        if (Objects.equals(shopDetail.getShopStatus(), ShopStatus.OFFLINE.value())) {
            throw new LuckException("店铺处于违规下线状态，不能发布新商品");
        }
        spuDTO.setShopCategoryId(Constant.DEFAULT_ID);
        spuDTO.setSpuType(SpuType.SCORE.value());
        spuDTO.setStatus(StatusEnum.ENABLE.value());
        spuDTO.setSupplierSpuType(SupplierSpuType.NO.value());
        spuDTO.setShopId(0L);
        spuService.save(spuDTO);
        return ServerResponseEntity.success();
    }

    @PutMapping("/auditSpu")
    @Operation(summary = "商品审核" , description = "商品审核")
    public ServerResponseEntity<Void> auditSpu(@RequestBody OfflineHandleEventDTO eventDTO) {
        eventDTO.setHandlerId(AuthUserContext.get().getUserId());
        spuService.auditSpu(eventDTO);
        // 移除缓存
        spuService.removeSpuCacheBySpuId(eventDTO.getHandleId());
        return ServerResponseEntity.success();
    }

    @PostMapping("/sold_excel")
    @Operation(summary = "导出excel" , description = " 导出商品excel")
    public ServerResponseEntity<Void> spuSoldExcel(HttpServletResponse response, @RequestBody ProductSearchDTO productSearchDTO) {
        List<PlatformSpuExcelVO> list = spuExcelService.excelPlatformSpuList(productSearchDTO);
        ExcelUtil.soleExcel(response, list, PlatformSpuExcelVO.EXCEL_NAME, PlatformSpuExcelVO.MERGE_ROW_INDEX, PlatformSpuExcelVO.MERGE_COLUMN_INDEX, PlatformSpuExcelVO.class);
        return ServerResponseEntity.success();
    }

    @GetMapping("/group_cate_by_area")
    @Operation(summary = "商品分类统计（数据大屏）" , description = "商品分类统计（数据大屏）")
    public ServerResponseEntity<List<Map<String,Object>>> group_cate_by_area(Long areaId) {
        return ServerResponseEntity.success(spuService.countByCateIdAndAreaId(areaId));
    }

    @GetMapping("/count_by_shop")
    @Operation(summary = "商品数量商家排序统计（数据大屏）" , description = "商品数量商家排序统计（数据大屏）")
    public ServerResponseEntity<List<Map<String,Object>>> count_by_shop( ) {
        return ServerResponseEntity.success(spuService.countByShop());
    }

    /**
     * 更新商品状态
     */
    @PutMapping("/prod_status")
    @Operation(summary = "商品上下架" , description = "商品上下架")
    public ServerResponseEntity<Void> spuChangeStatus(@RequestBody SpuPageSearchDTO spuDTO) {
        if (Objects.nonNull(spuDTO.getSpuId())) {
            spuDTO.setSpuIds(Collections.singletonList(spuDTO.getSpuId()));
        }
        if (CollUtil.isEmpty(spuDTO.getSpuIds())) {
            throw new LuckException("商品id不能为空");
        }
        Long shopId = spuDTO.getShopId();
        List<SpuVO> spuList = spuService.listSpuBySpuIds(spuDTO.getSpuIds());

        if(Objects.equals(spuDTO.getStatus(),StatusEnum.ENABLE.value()) && !Objects.equals(spuDTO.getShopId(), Constant.PLATFORM_SHOP_ID)){
            // 上架商品时，需要根据店铺状态判断是否可以上架商品
            ServerResponseEntity<EsShopDetailBO> shopRequest = shopDetailFeignClient.getShopByShopId(spuDTO.getShopId());
            EsShopDetailBO shopDetail = shopRequest.getData();
            if (!Objects.equals(shopDetail.getShopStatus(), ShopStatus.OPEN.value())) {
                // 合同到期
                if(shopDetail.getContractEndTime().compareTo(new Date()) < 0){
                    throw new LuckException("店铺有效期已过，不能进行此操作，请联系管理员后重试");
                }
                throw new LuckException("店铺处于违规下线状态，不能上架商品");
            }
        }
        for (SpuVO spuVO : spuList) {
            if(Objects.equals(spuDTO.getStatus(),StatusEnum.ENABLE.value())) {
                if(!Objects.equals(spuVO.getSpuType(), SpuType.SCORE.value())){
                    CategoryVO category = categoryService.getInfo(spuVO.getCategoryId());
                    if (category == null || Objects.equals(category.getStatus(), StatusEnum.DISABLE.value())) {
                        // 平台分类处于下线中，商品不能上架，请联系管理员后再进行操作
                        throw new LuckException("商品【" + spuVO.getName() + "】的平台分类处于下线中，商品不能上架，请联系管理员后再进行操作");
                    }
                    boolean write = Objects.equals(spuVO.getSpuMold(), 1) && !Objects.equals(0, spuVO.getWriteOffNum()) &&
                            Objects.equals(spuVO.getWriteOffTime(), 0) && Objects.nonNull(spuVO.getWriteOffEnd()) && new Date().after(spuVO.getWriteOffEnd());
                    if(write){
                        //商品已过核销有效期
                        throw new LuckException("该商品已过核销有效期");
                    }
                    if(!Objects.equals(spuVO.getSpuType(), SpuType.SCORE.value())) {
                        CategoryVO shopCategory = categoryService.getById(spuVO.getShopCategoryId());
                        if (shopCategory == null || Objects.equals(shopCategory.getStatus(), StatusEnum.DISABLE.value())) {
                            // 本店分类处于下线中，商品不能上架
                            throw new LuckException("商品【" + spuVO.getName() + "】的本店分类处于下线中，商品不能上架");
                        }
                    }
                }
                // 商家代销的供应商商品上架，如果是仓库发货，需要检验是否存在物流模板id了
                if (Objects.equals(spuVO.getSupplierSpuType(), SupplierDeliveryType.SHOP_DELIVERY.value()) && Objects.isNull(spuVO.getDeliveryTemplateId())) {
                    // 请先设置商品的物流模板
                    throw new LuckException("请先设置商品的物流模板： 商品名称【" + spuVO.getName() + "】");
                }
                // 如果商品正在下架，但又是活动商品，代表这个商品所属的活动被平台下架了
                if (Objects.equals(spuVO.getSpuType(), SpuType.SECKILL.value())) {
                    throw new LuckException("商品【" + spuVO.getName() + "】所属的秒杀活动处于违规下线中，商品不能上架");
                }
                if (Objects.equals(spuVO.getSpuType(), SpuType.GROUP.value())) {
                    throw new LuckException("商品【" + spuVO.getName() + "】所属的团购活动处于违规下线中，商品不能上架");
                }
            }
            //供应商商品
            if (SupplierSpuType.YES.value().equals(spuDTO.getSupplierSpuType())){
                SpuVO spuVo = spuService.getSpuByShopIdAndSupplierSpuId(shopId, spuDTO.getSpuId());
                if (!Objects.isNull(spuVo)){
                    spuDTO.setSpuId(spuVo.getSpuId());
                    spuDTO.setShopId(spuVo.getShopId());
                    spuVO.setShopId(spuVo.getShopId());
                }
            }
            if (!Objects.equals(spuVO.getShopId(), shopId) && !Objects.equals(shopId, Constant.PLATFORM_SHOP_ID)) {
                return ServerResponseEntity.fail(ResponseEnum.UNAUTHORIZED);
            }
        }
        // 是否开启“商品发布时审核”，若开启，上架修改状态为“待审核”【平台端不用审核】
        String prodSwitchConfig = configFeignClient.getConfig(Constant.SPU_SWITCH_CONFIG).getData();
        if (SpuStatus.PUT_SHELF.value().equals(spuDTO.getStatus())
                && !SysTypeEnum.PLATFORM.value().equals(AuthUserContext.get().getSysType())
                && !ObjectUtils.isEmpty(prodSwitchConfig)) {
            Boolean spuAudit = JSON.parseObject(prodSwitchConfig, new TypeReference<Map<String, Boolean>>(){})
                    .getOrDefault("spuAudit", false);
            if (spuAudit) {
                spuDTO.setStatus(SpuStatus.PUBLISH_WAIT_AUDIT.value());
            }
        }
        spuBatchUpdateStatus(spuDTO);
        for (SpuVO spuVO : spuList) {
            spuService.removeSpuCacheBySpuId(spuVO.getSpuId());
        }
        //  清除购物车数量缓存
        shopCartService.removeShopCartItemCache(spuDTO.getSpuIds());
        return ServerResponseEntity.success();
    }

    /**
     * spu批量上下架
     * @param spuDTO
     */
    private void spuBatchUpdateStatus(SpuPageSearchDTO spuDTO) {
        List<Long> spuIds = spuDTO.getSpuIds();
        Integer status = spuDTO.getStatus();
        spuDTO.setStatus(null);
        List<SpuVO> spuList = new ArrayList<>();
        if (Objects.equals(spuDTO.getSupplierSpuType(), SupplierSpuType.CONSIGNMENT.value())){
            spuList = spuService.supplierSpuList(spuDTO);
        }else {
            spuList = spuService.list(spuDTO);
        }
        if (CollUtil.isEmpty(spuList)) {
            throw new LuckException("获取不到该商品信息，请刷新后重试");
        }
        checkUpdateStatusData(spuList, status,spuDTO.getShopId());
        if (CollUtil.isEmpty(spuIds)) {
            throw new LuckException("您所选择的商品中没有符合操作条件的商品");
        }
        spuService.batchChangeSpuStatus(spuIds, status);
    }

    /**
     * 校验spu上下架信息
     * @param list 商品列表
     * @param status 更新的状态
     * @return
     */
    private void checkUpdateStatusData(List<SpuVO> list, Integer status,Long shopId) {
        ProductLangUtil.spuList(list);
        ServerResponseEntity<EsShopDetailBO> shopRequest = shopDetailFeignClient.getShopByShopId(shopId);
        EsShopDetailBO shopDetail = shopRequest.getData();
        if (Objects.equals(shopDetail.getShopStatus(), ShopStatus.OFFLINE.value()) || Objects.equals(shopDetail.getShopStatus(), ShopStatus.OFFLINE_AWAIT_AUDIT.value())) {
            throw new LuckException("店铺处于违规下线中，不能修改商品");
        }
        for (SpuVO spu : list) {
//            if (!Objects.equals(spu.getShopId(), shopId) && !Objects.equals(AuthUserContext.get().getTenantId(), Constant.PLATFORM_SHOP_ID)) {
//                throw new LuckException(ResponseEnum.UNAUTHORIZED);
//            }
            // 商品状态不为启用或未启用状态
            if (!Objects.equals(spu.getStatus(), StatusEnum.ENABLE.value())
                    && !Objects.equals(spu.getStatus(), StatusEnum.DISABLE.value())) {
                throw new LuckException("商品(" + spu.getName() + ")不能进行上下架操作");
            }
            if(Objects.equals(status, StatusEnum.ENABLE.value()) && !Objects.equals(spu.getSpuType(), SpuType.SCORE.value())){
                CategoryVO category = categoryService.getById(spu.getCategoryId());
                if (!Objects.equals(category.getStatus(), StatusEnum.ENABLE.value())){
                    throw new LuckException("商品(" + spu.getName() +")所属的平台分类处于下线中，商品不能进行上架操作，请联系管理员后再进行操作");
                }
                if (!Objects.equals(spu.getSpuType(), SpuType.SCORE.value())) {
                    CategoryVO shopCategory = categoryService.getById(spu.getShopCategoryId());
                    if (!Objects.equals(shopCategory.getStatus(), StatusEnum.ENABLE.value())) {
                        throw new LuckException("商品(" + spu.getName() + ")所属的店铺分类处于下线中，商品不能进行上架操作");
                    }
                    CategoryShopVO categoryShopVO = categoryShopService.getByShopIdAndCategoryId(spu.getShopId(), spu.getCategoryId(), 1);
                    if (Objects.isNull(categoryShopVO)) {
                        throw new LuckException("商品(" + spu.getName() + ")所属的平台分类与店铺的签约关系已失效，商品不能进行上架操作");
                    }
                }
            }
        }
    }
}
